package com.imax.center.service.impl;

import com.alibaba.fastjson.JSON;
import com.imax.center.common.Result;
import com.imax.center.service.CommonService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 通用功能服务实现类
 */
@Slf4j
@Service
public class CommonServiceImpl implements CommonService {

    @Autowired
    private RestTemplate restTemplate;

    @Value("${config.upload.image-path}")
    private String imageUploadPath;

    @Value("${config.domain}")
    private String domain;

    /**
     * 获取行政区划边界GeoJSON数据
     * 调用阿里云数据可视化服务API获取行政区划边界数据
     *
     * @param areaCode 行政区划代码
     * @return GeoJSON数据
     */
    @Override
    public Object getAreaBoundary(String areaCode) {
        try {
            // 构建请求URL
            String url = "https://geo.datav.aliyun.com/areas_v3/bound/" + areaCode + "_full.json";

            // 设置请求头
            HttpHeaders headers = new HttpHeaders();
            headers.set("referer", "https://geo.datav.aliyun.com");

            // 创建HTTP实体
            HttpEntity<String> entity = new HttpEntity<>(headers);

            // 发送请求获取结果
            ResponseEntity<String> responseEntity = restTemplate.exchange(
                    url,
                    HttpMethod.GET,
                    entity,
                    String.class);

            // 获取响应内容
            String responseBody = responseEntity.getBody();

            // 解析响应结果为JSON对象
            return JSON.parse(responseBody);
        } catch (Exception e) {
            log.error("获取行政区划边界数据异常", e);
            return Result.error("获取行政区划边界数据异常：" + e.getMessage());
        }
    }

    /**
     * 保存图片
     *
     * @param file     上传的图片文件
     * @param fileName 图片名称
     * @return 图片保存路径
     * @throws IOException 如果保存过程中发生IO异常
     */
    @Override
    public String saveImage(MultipartFile file, String fileName) throws IOException {
        // 文件类型判断
        // String fileType = file.getContentType();
        // if (fileType == null || !fileType.equals("image/jpeg") &&
        // !fileType.equals("image/png") && !fileType.equals("image/gif")) {
        // throw new IOException("文件类型不支持");
        // }

        String originalFilename = file.getOriginalFilename();
        String fileExtension = ".jpg"; // 默认值为.jpg
        if (originalFilename != null && originalFilename.contains(".")) {
            fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
        }

        // 获取当前月份，格式为yyyyMM
        String currentMonth = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMM"));
        
        // 构建包含月份的完整上传路径
        String monthUploadPath = imageUploadPath + File.separator + currentMonth + File.separator;
        
        // 检查上传目录是否存在，不存在则创建
        File uploadDir = new File(monthUploadPath);
        if (!uploadDir.exists()) {
            uploadDir.mkdirs();
        }

        String newFileName = "";
        // 如果fileName为空，则生成文件名
        if (fileName == null || fileName.isEmpty()) {
            // 使用日期和UUID生成唯一文件名
            String dateStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
            newFileName = dateStr + "_" + UUID.randomUUID().toString().replace("-", "") + fileExtension;
        } else {
            newFileName = fileName + fileExtension;
        }

        // 构建文件存储路径
        String filePath = monthUploadPath + newFileName;
        Path path = Paths.get(filePath);

        // 保存文件
        Files.copy(file.getInputStream(), path);

        log.info("图片已保存: {}", filePath);

        // 组装图片绝对路径，包含月份信息
        return domain + "/image/download?url=" + currentMonth + "/" + newFileName;
    }

    @Override
    public String saveImageDrawEle(MultipartFile file, Map<String, Object> map, String fileName) throws IOException {
        // 检查文件是否为空
        if (file.isEmpty()) {
            throw new IllegalArgumentException("上传文件不能为空");
        }

        // 读取原始图片
        BufferedImage image = ImageIO.read(file.getInputStream());
        if (image == null) {
            throw new IOException("不支持的文件格式");
        }

        // 创建绘图上下文
        Graphics2D graphics = image.createGraphics();
        try {
            // 设置抗锯齿和文本渲染参数
            graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

            // 设置字体（使用系统可用字体）
            Font font = new Font("微软雅黑", Font.PLAIN, 28);
            graphics.setFont(font);
            graphics.setColor(Color.RED);

            int x = 20;
            int y = 150;

            //遍历content
            int i = 0;
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue().toString();
                String str = key + " = " + value;
                graphics.drawString(str, x, y + (i * 36));
                i++;
            }
        } finally {
            graphics.dispose();
        }

        // 获取当前月份，格式为yyyyMM
        String currentMonth = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMM"));
        
        // 构建包含月份的完整上传路径
        String monthUploadPath = imageUploadPath + File.separator + currentMonth + File.separator;

        // 创建保存目录
        File dir = new File(monthUploadPath);
        if (!dir.exists() && !dir.mkdirs()) {
            throw new IOException("无法创建保存目录");
        }

        // 生成唯一文件名并保存
        String originalName = file.getOriginalFilename();
        String extension = originalName != null && originalName.contains(".")
                ? originalName.substring(originalName.lastIndexOf("."))
                : ".jpg";

        // 如果fileName为空，则生成文件名
        String newFileName = "";
        if (fileName == null || fileName.isEmpty()) {
            newFileName = UUID.randomUUID().toString().replace("-", "") + extension;
        } else {
            newFileName = fileName + extension;
        }

        String filePath = monthUploadPath + newFileName;

        // 保持原始格式保存图片
        String formatName = extension.substring(1).toLowerCase();
        if (!ImageIO.write(image, formatName, new File(filePath))) {
            throw new IOException("不支持的图片格式：" + formatName);
        }

        return domain + "/image/download?url=" + currentMonth + "/" + newFileName;
    }

    /**
     * 根据路径获取图片输入流
     *
     * @param imagePath 图片路径（文件名，可能包含月份目录）
     * @return 图片输入流，如果图片不存在则返回null
     * @throws IOException 如果获取过程中发生IO异常
     */
    @Override
    public InputStream getImageInputStream(String imagePath) throws IOException {
        // 构建完整文件路径
        String fullPath = imageUploadPath + imagePath;
        File imageFile = new File(fullPath);

        // 检查文件是否存在
        if (!imageFile.exists() || !imageFile.isFile()) {
            log.error("图片不存在: {}", fullPath);
            return null;
        }

        // 返回文件输入流
        return new FileInputStream(imageFile);
    }

    /**
     * 根据文件路径删除文件
     *
     * @param filePath 文件路径（可以是相对路径或绝对路径）
     * @return 删除结果，true表示删除成功，false表示文件不存在或删除失败
     */
    @Override
    public boolean deleteFile(String filePath) {
        if (filePath == null || filePath.trim().isEmpty()) {
            log.warn("文件路径为空，无法删除文件");
            return false;
        }

        try {
            // 构建完整文件路径
            String fullPath;
            if (filePath.startsWith("/") || filePath.contains(":")) {
                // 如果是绝对路径，直接使用
                fullPath = filePath;
            } else {
                // 如果是相对路径，拼接上传目录
                fullPath = imageUploadPath + File.separator + filePath;
            }

            File file = new File(fullPath);
            
            // 检查文件是否存在
            if (!file.exists()) {
                log.info("文件不存在，无需删除: {}", fullPath);
                return false;
            }

            // 检查是否为文件（不是目录）
            if (!file.isFile()) {
                log.warn("路径指向的不是文件，无法删除: {}", fullPath);
                return false;
            }

            // 检查文件是否可写
            if (!file.canWrite()) {
                log.warn("文件不可写，无法删除: {}", fullPath);
                return false;
            }

            // 执行删除操作
            boolean deleted = file.delete();
            if (!deleted) {
                log.warn("文件删除失败: {}", fullPath);
            }
            
            return deleted;
            
        } catch (SecurityException e) {
            log.error("删除文件时发生安全异常: {}", filePath, e);
            return false;
        } catch (Exception e) {
            log.error("删除文件时发生异常: {}", filePath, e);
            return false;
        }
    }

    @Override
    public List<String> listAllImageFiles() {
        java.util.List<String> fileList = new java.util.ArrayList<>();
        java.io.File dir = new java.io.File(imageUploadPath);
        if (!dir.exists() || !dir.isDirectory()) {
            return fileList;
        }
        listFilesRecursive(dir, fileList, dir.getAbsolutePath());
        return fileList;
    }

    /**
     * 递归遍历目录，收集所有文件的相对路径
     */
    private void listFilesRecursive(java.io.File dir, java.util.List<String> fileList, String rootPath) {
        for (java.io.File file : dir.listFiles()) {
            if (file.isDirectory()) {
                listFilesRecursive(file, fileList, rootPath);
            } else {
                // 只返回相对路径
                String relativePath = file.getAbsolutePath().substring(rootPath.length());
                // 兼容不同系统的分隔符
                relativePath = relativePath.replace(java.io.File.separatorChar, '/');
                if (relativePath.startsWith("/")) {
                    relativePath = relativePath.substring(1);
                }
                fileList.add(relativePath);
            }
        }
    }
}